// ++++++++++++++++++++++++++++++++++++++++
// 《零基础Go语言算法实战》源码
// ++++++++++++++++++++++++++++++++++++++++
// Author:廖显东（ShirDon）
// Blog:https://www.shirdon.com/
// Gitee:https://gitee.com/shirdonl/goAlgorithms.git
// Buy link :https://item.jd.com/14101229.html
// ++++++++++++++++++++++++++++++++++++++++

package main

import "fmt"

func main() {
	input := [][]byte{
		{'5', '3', '.', '.', '7', '.', '.', '.', '.'},
		{'6', '.', '.', '1', '9', '5', '.', '.', '.'},
		{'.', '9', '8', '.', '.', '.', '.', '6', '.'},
		{'8', '.', '.', '.', '6', '.', '.', '.', '3'},
		{'4', '.', '.', '8', '.', '3', '.', '.', '1'},
		{'7', '.', '.', '.', '2', '.', '.', '.', '6'},
		{'.', '6', '.', '.', '.', '.', '2', '8', '.'},
		{'.', '.', '.', '4', '1', '9', '.', '.', '5'},
		{'.', '.', '.', '.', '8', '.', '.', '7', '9'},
	}

	// 解决难题
	solveSudoku(input)

	// 打印解决方案
	for i := 0; i < 9; i++ {
		for j := 0; j < 9; j++ {
			fmt.Printf("%c ", input[i][j])
		}
		fmt.Printf("\n")
	}
}

// 解决数独的入口点
func solveSudoku(board [][]byte) {
	solve(board)
}

// 递归函数，它尝试用 1 到 9 之间的数字填充每个空单元格
// 如果拼图已解决则返回 true，否则返回 false
func solve(board [][]byte) bool {
	for i := 0; i < 9; i++ {
		for j := 0; j < 9; j++ {
			if board[i][j] == '.' {
				for c := byte('1'); c <= '9'; c++ {
					if isValid(board, i, j, c) {
						board[i][j] = c
						if solve(board) {
							return true
						}
						board[i][j] = '.'
					}
				}
				return false
			}
		}
	}
	return true
}

// 检查当前值 c 是否可以放在棋盘的给定行和列中
// 如果 c 是单元格的有效选择，则返回 true，否则返回 false
func isValid(board [][]byte, row, col int, c byte) bool {
	for i := 0; i < 9; i++ {
		if board[i][col] == c {
			return false
		}
		if board[row][i] == c {
			return false
		}
		if board[3*(row/3)+i/3][3*(col/3)+i%3] == c {
			return false
		}
	}
	return true
}

//$ go run interview11.3.go
//5 3 4 6 7 8 9 1 2
//6 7 2 1 9 5 3 4 8
//1 9 8 3 4 2 5 6 7
//8 5 9 7 6 1 4 2 3
//4 2 6 8 5 3 7 9 1
//7 1 3 9 2 4 8 5 6
//9 6 1 5 3 7 2 8 4
//2 8 7 4 1 9 6 3 5
//3 4 5 2 8 6 1 7 9
